﻿using System.Web.Mvc;
using Autofac;
using Autofac.Integration.Mvc;
using DDDSample.Application.Book;
using DDDSample.Application.HandlingEvent;
using DDDSample.Application.PathFinder;
using DDDSample.Application.Routing;
using DDDSample.Domain.NHibernate.Mappings;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Tool.hbm2ddl;

namespace DDDSample.UI.Mvc
{
    public static class IocHelper
    {
        private static readonly ContainerBuilder Builder = new ContainerBuilder();

        internal static IContainer Container { get; private set; }

        internal static void Init()
        {
            RegisterNHibernate();
            RegisterAppServices();
            RegisterControllers();
            Container = Builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));
        }

        private static void RegisterNHibernate()
        {
            Builder.Register(c => BuildSessionFactory()).As<ISessionFactory>().SingleInstance();
        }

        private static void RegisterAppServices()
        {
            Builder.Register(c => new HandlingEventService(c.Resolve<ISessionFactory>().GetCurrentSession())).As<IHandlingEventService>();
            Builder.Register(c => new GraphTraversalService(c.Resolve<ISessionFactory>().GetCurrentSession())).As<IGraphTraversalService>();
            Builder.Register(c => new BookService(c.Resolve<ISessionFactory>().GetCurrentSession(), c.Resolve<IRoutingService>())).As<IBookService>();
            Builder.Register(c => new RoutingService(c.Resolve<ISessionFactory>().GetCurrentSession(), c.Resolve<IGraphTraversalService>())).As<IRoutingService>();
        }

        private static void RegisterControllers()
        {
            Builder.RegisterControllers(typeof(IocHelper).Assembly);
        }

        internal static ISessionFactory BuildSessionFactory(bool buildTables = false)
        {
            return Fluently.Configure()
                .Database(SQLiteConfiguration.Standard.ShowSql().ConnectionString(c => c.FromConnectionStringWithKey("ddd")))
                .CurrentSessionContext("web")
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<CargoMap>()).ExposeConfiguration(c =>
                {
                    c.SetInterceptor(new SqlInterceptor());
                    if (buildTables)
                    {
                        var schema = new SchemaExport(c);
                        schema.Execute(false, true, false);
                    }
                }).BuildSessionFactory();
        }
    }
}